/*
 * posix_mq_utils.c
 *
 *  Created on: 25/12/2012
 *      Author: Julian Ovalle
 */

#include <mqueue.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <time.h>
#include <sys/stat.h>

#include "posix_mq_utils.h"

int pmsgq_receive(int msqid, void *buf, unsigned int size,
        unsigned int* prio, unsigned int timeout_msec, unsigned int timeout_sec) {

    struct timeval timeout;
    fd_set fds;
    timeout.tv_sec = timeout_sec;
    timeout.tv_usec = timeout_msec * 1000;
    FD_ZERO(&fds);
    FD_SET(msqid, &fds);

    if (select(FD_SETSIZE, &fds, NULL, NULL, &timeout) > 0) {
        if (mq_receive(msqid, (char*) buf, size, prio) < 0) {
#ifdef MQ_UTILS_DEBUG
            perror("mq_receive");
#endif
            return -2;
        }
        return 0;
    } else {
#ifdef MQ_UTILS_DEBUG
        fprintf(stderr, "\n msgq_receive timeout");
#endif
        return -1;
    }
    return 0;
}

int pmsgq_send(int msqid, void * buf, unsigned int size, int prio,
        unsigned int timeout_msec, unsigned int timeout_sec) {

    struct timeval timeout;
    fd_set fds;
    timeout.tv_sec = timeout_sec;
    timeout.tv_usec = timeout_msec * 1000;
    FD_ZERO(&fds);
    FD_SET(msqid, &fds);

    if (select(FD_SETSIZE, NULL, &fds, NULL, &timeout) > 0) {
        if (mq_send(msqid, (char*) buf, size, (unsigned)prio) < 0) {
#ifdef MQ_UTILS_DEBUG
            perror("mq_send");
#endif
            return -2;
        }
        return 0;
    } else {
        fprintf(stderr, "\n msgq_send timeout");
        return -1;
    }
}

int pmsgq_create(char* name, int maxmsg, size_t msgsize) {

    int msqid;
    struct mq_attr attr;
    attr.mq_maxmsg = maxmsg;
    attr.mq_msgsize = msgsize;

    if ((msqid = mq_open(name, O_CREAT | O_RDWR, S_IRWXU, &attr)) == -1) {
#ifdef MQ_UTILS_DEBUG
        fprintf(stderr, "Error %d opening mq: %s\n", errno, strerror(errno));
#endif
        return -1;
    }
    return msqid;
}

int pmsgq_destroy(char* name, int mqdes) {

    if (mq_unlink(name) == -1) {
#ifdef MQ_UTILS_DEBUG
        fprintf(stderr, "msgq_destroy:Error %d al destruir la cola: %s\n",
                errno, strerror(errno));
#endif
        return -1;
    }

    if (mq_close(mqdes) == -1) {
#ifdef MQ_UTILS_DEBUG
        fprintf(stderr, "msgq_destroy:Error %d al destruir la cola: %s\n",
                errno, strerror(errno));
#endif
        return -1;
    }

    return 0;
}

